-
Notifications
You must be signed in to change notification settings - Fork 220
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enumerator based coroutine yielding #281
base: master
Are you sure you want to change the base?
Conversation
Oh, usecase The usecase for this would be nicer yielding in api functions while we wait for things to happen/be ready dialogue:say("Hello please give me your name")
local name = dialogue:input()
dialogue:clear()
dialogue:say("Hi ".. name) Currently |
var enumerateYielder = script.DoString(@"return function (callable) | ||
return function (...) | ||
for y in callable(...) do | ||
if coroutine.is_return_value(y) then | ||
return coroutine.get_return_value(y) | ||
else | ||
coroutine.yield(y) | ||
end | ||
end | ||
end | ||
end", null, MethodInfo + "_yielder"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it make sense to parse this lua code one for performance reasons? Could this lua function be pulled out and kept as a global function to be used when needed? I've done something similar in my own code, though all on the lua side without the C# interconnection work this PR does to make it nice and clean.
Yeah, in a final version you'd want to get rid of the lua code parsing and clean up the code all together
This is just a proof of concept, it also has issues of not yielding null values, since those aren't valid in lua "iterators"
I wouldn't recommend using this as is
… On 2 Sep 2020, at 22:04, Chris Smoak ***@***.***> wrote:
@cesmoak commented on this pull request.
In src/MoonSharp.Interpreter/Interop/StandardDescriptors/ReflectionMemberDescriptors/MethodMemberDescriptorCoroutine.cs:
> + var enumerateYielder = script.DoString(@"return function (callable)
+ return function (...)
+ for y in callable(...) do
+ if coroutine.is_return_value(y) then
+ return coroutine.get_return_value(y)
+ else
+ coroutine.yield(y)
+ end
+ end
+ end
+end", null, MethodInfo + "_yielder");
Does it make sense to parse this lua code one for performance reasons? Could this lua function be pulled out and kept as a global function to be used when needed? I've done something similar in my own code, though all on the lua side without the C# interconnection work this PR does to make it nice and clean.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
Hey!
One of the features that's missing from moonsharp that'd make writing lua code a lot more elegant would be support for yielding a coroutine in clr functions
In unity this is usually done by just having an enumerator/generator function (not sure of the 100% correct terminology):
You can do something like this already, but you'll have to manually keep track of the iterator:
Conceptually it shouldn't be too hard to just add some "syntactical sugar" to implement something similar to the lua function above behind the scenes..
So I decided to give that a try and went digging
First I looked at the custom converters and figured it'd be as easy as checking for an attribute on the method info and just giving it a different DynValue with the "for loop yield" part, but turns out classes don't even use that and I had to go a lot deeper
This is obviously a giant hack at the moment and I'm mainly looking for feedback to get this to a decent state where merging it might be considered
The whole MethodMemberDescriptor part can be implemented better, but I didn't want to dig too deep into the scary parts for a proof of concept
I'm also curious what the best way would be to generate the iterator wrapper part? From what I gathered the yield does need to be run in bytecode currently